package cac.fenjian.resource.materialreceipt.util;

import cac.common.CallInterFace.dao.CallInterFaceDao;
import cac.common.CallInterFace.rest.SendMaterialInterface;
import cac.common.CallInterFace.service.CallInterfaceService;
import cac.common.CreatMsgId;
import cac.fenjian.resource.WmsDeliverPlan.dto.WmsDeliverPlanDTO;
import cac.fenjian.resource.finProReceiveSearch.service.FinProReceiveSearchService;
import cac.fenjian.resource.materialreceipt.dao.WmsItemInventoryDao;
import cac.fenjian.resource.partreceivesearch.service.PartReceiveService;
import cac.fenjian.resource.wmsdeliverplan.dao.WmsDeliverPlanDao;
import cac.gkinterface.service.WorkService;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.cac.dme.adapter.rest.msg.ResponseMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class MaterialReceiptSyn {
    @Autowired
    private WmsItemInventoryDao wmsItemInventoryDao;
    @Autowired
    private FinProReceiveSearchService finProReceiveSearchService;
    @Autowired
    private Environment environment;
    @Autowired
    private PartReceiveService partReceiveService;
    @Autowired
    private WmsDeliverPlanDao wmsDeliverPlanDao;
    @Autowired
    private WorkService workService;
    @Autowired
    private CallInterfaceService callInterfaceService;
    @Autowired
    private SendMaterialInterface sendMaterialInterface;
    @Autowired
    private CallInterFaceDao callInterFaceDao;
    @Autowired
    private AsyncLog asyncLog;

    @Async
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendItemInventoryToErpSyn(WmsDeliverPlanDTO planDTO,String WmsItemInventoryId,String account,String IP){
        HashMap aLog = new HashMap();
        aLog.put("businessVal",WmsItemInventoryId);
        try {
            asyncLog.updateAsyncLogExe(aLog);

            JSONObject headersMap = new JSONObject();
            HashMap issuedTest = new HashMap();
            HashMap senBData = new HashMap();
            issuedTest.put("businessTab","wms_item_inventory_id");
            issuedTest.put("businessCol","wms_item_inventory");
            issuedTest.put("businessVal",WmsItemInventoryId);
            log.info("------------准备推送台账---------第1步-------WmsItemInventoryId:"+WmsItemInventoryId);
            String func = wmsItemInventoryDao.searchFunc(planDTO.getWmsDeliveryPlanId());
            if (func.equals("ERP-101-preConfirmCp")) {
                //查询是否发起协调
                HashMap hashMap = finProReceiveSearchService.searchCoordinate(planDTO.getWmsDeliveryPlanId());
                if (Objects.isNull(hashMap)) {
                    log.info("============================工控网上传_成品接收==========================");
                    headersMap.put("func", environment.getProperty("doReturnErp.doCpDeliveryReceiveErp.func"));
                    //工控网上传数据
                    issuedTest.put("type", environment.getProperty("doReturnErp.doCpDeliveryReceiveErp.func"));

                } else {
                    log.info("============================工控网上传_成品归零接收==========================");
                    String WMS_DELIVERY_COORDINATE_ID = (String) hashMap.get("WMS_DELIVERY_COORDINATE_ID");
                    headersMap.put("func", environment.getProperty("doReturnErp.scanZeroReceiveCp.func"));
                    senBData.put("wmsCoordinateInfoId", WMS_DELIVERY_COORDINATE_ID);
                    //工控网上传数据
                    issuedTest.put("type", environment.getProperty("doReturnErp.scanZeroReceiveCp.func"));
                }
            } else if (func.equals("ERP-101-preConfirmLj")) {
                //查询是否发起协调
                HashMap hashMap = partReceiveService.searchCoordinate(planDTO.getWmsDeliveryPlanId());
                if (Objects.isNull(hashMap)) {
                    log.info("===========================工控网上传_零件接收===========================");
                    headersMap.put("func", environment.getProperty("doReturnErp.materialReviceRetrunErp.func"));
                    senBData.put("sealDate", planDTO.getSealDate() == null ? " " : planDTO.getSealDate());
                    senBData.put("ensureDate", planDTO.getEnsureDate() == null ? " " : planDTO.getEnsureDate());
                    senBData.put("maxStorageDate", planDTO.getMaxStorageDate() == null ? " " : planDTO.getMaxStorageDate());
                    senBData.put("recieveNote", planDTO.getReceiveRemark() == null ? " " : planDTO.getReceiveRemark());
                    //工控网上传数据
                    issuedTest.put("type", environment.getProperty("doReturnErp.materialReviceRetrunErp.func"));

                } else {
                    log.info("============================工控网上传_零件归零接收==========================");
                    String WMS_DELIVERY_COORDINATE_ID = (String) hashMap.get("WMS_DELIVERY_COORDINATE_ID");
                    headersMap.put("func", environment.getProperty("doReturnErp.scanZeroReceiveLj.func"));
                    senBData.put("wmsCoordinateInfoId", WMS_DELIVERY_COORDINATE_ID);
                    //工控网上传数据
                    issuedTest.put("type", environment.getProperty("doReturnErp.scanZeroReceiveLj.func"));
                }
            } else {
                log.info("============================工控网上传_标准件扫码接收==========================");
                headersMap.put("func", environment.getProperty("doReturnErp.scanRecieveBzj.func"));
                //工控网上传数据
                issuedTest.put("type", environment.getProperty("doReturnErp.scanRecieveBzj.func"));
            }
            log.info("------------准备推送台账---------第2步-------WmsItemInventoryId:"+WmsItemInventoryId);
            //yebo 2023-04-09 修改，查询移交数量
            int deliveryQty = wmsDeliverPlanDao.queryDeliveryQtyFromWmsDelivery(planDTO);
            senBData.put("wmsPreDeliveryPlanId", planDTO.getWmsDeliveryPlanId());
            senBData.put("wmsItemInventoryId", WmsItemInventoryId);
            //查询是无库存交接
            HashMap ret = wmsDeliverPlanDao.searchDeliveryType(planDTO.getWmsDeliveryPlanId());
            //2023-11-03 yebo 调整 内容
           /* if (!Objects.isNull(ret) && ret.containsKey("attribute5Desc")) {
                if ("NOINV".equals(ret.get("attribute5Desc"))) {
                    //2023-11-03 yebo 调整 190，与143库位号不一样
                    if("143".equals(ret.get("requireShop"))){
                        senBData.put("inventoryCode", "101-FJZX143");
                    }else{
                        senBData.put("inventoryCode", "101-FJZX");
                    }
                }
            }*/
            //2023-11-10 yebo 根据单位增加传递库位号
            if("143".equals(ret.get("requireShop"))){
                senBData.put("inventoryCode", "101-FJZX143");
            }else{
                senBData.put("inventoryCode", "101-FJZX");
            }
            log.info("------------准备推送台账---------第3步-------WmsItemInventoryId:"+WmsItemInventoryId);
            senBData.put("remark", planDTO.getReceiveRemark() == null ? " " : planDTO.getReceiveRemark());
            //获取当前库存代码
            senBData.put("locatorNo", environment.getProperty("doReturnErp.locatorNo.func"));
            senBData.put("recieveQty", deliveryQty);//此处应该用移交数量
            log.info("account:" + account);
            senBData.put("opUserCode", account);
            senBData.put("userIp", IP);
            JSONObject data = new JSONObject(senBData);
            headersMap.put("data", data);
            String msgId = CreatMsgId.getMsgId();
            headersMap.put("msgId", msgId);
            issuedTest.put("BData", headersMap.toJSONString());
            issuedTest.put("msgId", msgId);
            log.info("加密前BData：" + headersMap.toJSONString());
            log.info("工控网上传程序后台日志:>>>>>>>>>>>>WmsItemInventoryId:"+WmsItemInventoryId+">>>>>>>>>>>>>issuedParameters:" + issuedTest.toString());
            workService.issuedTest(issuedTest);
            log.info("------------准备推送台账----记录日志完成-----第4步-------WmsItemInventoryId:"+WmsItemInventoryId);
            //对已经转换成字符串的数据进行加密
            final Base64.Encoder encoder = Base64.getEncoder();
            String BData = encoder.encodeToString(headersMap.toJSONString().getBytes());
            log.info("加密后BData：" + BData);
            String parameters = BData;
            String code = "sendBData";
            String sendScenario = "物料接收入库";
            String name = "两网传输-发送业务数据";
            long beginTime = System.currentTimeMillis();
            log.info("======开始时间=======" + beginTime);
            HashMap sendRsl = callInterfaceService.sendBData(code, name, parameters, sendScenario);
            long endTime = System.currentTimeMillis();
            log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
            if ("201".equals(sendRsl.get("retCode"))) {
            }
            asyncLog.updateAsyncLogFinish(aLog);
            log.info("------------准备推送台账----推送完成-----第5步-------WmsItemInventoryId:"+WmsItemInventoryId);
        }catch (Exception e){
            log.info("---推送台账异常："+e.getMessage()+"---WmsItemInventoryId:"+WmsItemInventoryId);
            e.printStackTrace();
        }
    }


    /****
     * 2023-10-27 yebo 占用改成异步方式
     * */
    @Async
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendSortOccupy(String opUserCode,String IP,HashMap hashMap){
        HashMap aLog = new HashMap();
        aLog.put("businessVal",hashMap.get("originalId"));
        asyncLog.updateAsyncLogExe(aLog);
        //分拣占用，调用回传ERP
        String parameters = this.sortOccupy(opUserCode, IP, hashMap);
        String code = "sendBData";
        String sendScenario = "分拣占用";
        String name = "两网传输-发送业务数据";
        long beginTime = System.currentTimeMillis();
        log.info("======开始时间=======" + beginTime);
        callInterfaceService.sendBData(code, name, parameters, sendScenario);
        log.info("==========执行业务数据处理===========");
        long endTime = System.currentTimeMillis();
        log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
        asyncLog.updateAsyncLogFinish(aLog);
    }

    public String sortOccupy(String opUserCode, String IP, HashMap map) {
        JSONObject headersMap = new JSONObject();
        String msgId = CreatMsgId.getMsgId();
        //获取func
        headersMap.put("func", environment.getProperty("doReturnErp.sortOccupy.func"));
        headersMap.put("msgId", msgId);
        //分拣占用接口所需参数
        map.put("opUserCode", opUserCode);
        map.put("userIp", IP);
        map.put("taskNo", "");
        map.put("recHrDeptId", "");

        JSONObject data = new JSONObject(map);
        headersMap.put("data", data);
        String headersmap = headersMap.toJSONString();
        log.info("分拣占用上传ERP===============" + headersmap);
        //对已经转换成字符串的数据进行加密
        final Base64.Encoder encoder = Base64.getEncoder();
        String BData = encoder.encodeToString(headersmap.getBytes());
        log.info("==========================工控网上传_分拣占用============================");
        //工控网上传数据
        HashMap issuedTest = new HashMap();//originalId
        issuedTest.put("businessTab","wms_inv_out_allotment");
        issuedTest.put("businessCol","wms_inv_out_allotment_id");
        issuedTest.put("businessVal",map.get("originalId"));
        issuedTest.put("BData", headersmap);
        issuedTest.put("msgId", msgId);
        issuedTest.put("type", headersMap.get("func"));
        log.info("工控网上传程序后台日志:>>>>>>>>>>>>>>>>>>>>>>>>>issuedParameters:" + issuedTest.toString());
        log.info("==========================工控网上传_分拣占用============================");
        workService.issuedTest(issuedTest);
        return BData;
    }
    @Async
    public void sendSortingMsgToMES() {
        HashMap paramMap = new HashMap();
        paramMap.put("dmsCode", "ms_fjztsc");
        paramMap.put("is_sort", "N");
        HashMap interfaceMap = new HashMap();
        interfaceMap.put("code", "getMatchData");
        interfaceMap.put("name", "获取数据配套场景的配套数据");
        interfaceMap.put("parameters", paramMap);
        interfaceMap.put("func", "101-MES-MaterialState");
        interfaceMap.put("sendScenario", "分拣状态上传MES");
        try{
            sendMaterialInterface.SendFileInterface(interfaceMap);
        }catch (Exception e){
            log.info("****分拣保存上传MES分拣状态程序异常！");
            e.printStackTrace();
            log.info("****分拣保存上传MES分拣状态异常！");
        }
    }
    /**
     * 2023-11-02 yebo 添加
     * **/
    @Async
    public void sendRemark(HashMap receiveNote,String msgId){
        HashMap aLog = new HashMap();
        aLog.put("businessVal",receiveNote.get("wmsPreDeliveryPlanId"));
        asyncLog.updateAsyncLogExe(aLog);
        HashMap transRsl = new HashMap();
        JSONObject funcJson = new JSONObject(receiveNote);
        JSONObject resultOb = new JSONObject();
        resultOb.put("data", funcJson);
        resultOb.put("func", "101-ERP-saveRecieveLj");
        resultOb.put("msgId", msgId);
        //将组装好的月业务参数加密
        final Base64.Encoder encoder = Base64.getEncoder();
        String parameters = encoder.encodeToString(resultOb.toJSONString().getBytes());
        log.info("============================工控网上传_接收备注==========================");
        //调用网闸所需参数
        String code = "sendBData";
        String sendScenario = "接收备注";
        String name = "两网传输-发送业务数据";
        long beginTime = System.currentTimeMillis();
        log.info("======开始时间=======" + beginTime + "=========101-ERP-saveRecieveLj：" + resultOb.toJSONString());
        //调用接口发送业务数据
        transRsl = callInterfaceService.sendBData(code, name, parameters, sendScenario);
        long endTime = System.currentTimeMillis();
        log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
        log.info("============================工控网上传_接收备注==========================");
        //工控网上传数据
        HashMap issuedTest = new HashMap();
        issuedTest.put("BData", resultOb.toJSONString());
        issuedTest.put("type", resultOb.get("func"));
        issuedTest.put("msgId", msgId);
        issuedTest.put("result", transRsl.toString());
        workService.issuedTest(issuedTest);
        log.info("工控网上传程序后台日志:>>>>>>>>>>>>>>>>>>>issuedParameters:" + issuedTest.toString());
        asyncLog.updateAsyncLogFinish(aLog);
    }


    //将打包的数据上传  扫码移交接口使用了
    @Async
    public HashMap sendBData(String code, String name, String BData, String sendScenario) {

        HashMap entity = new HashMap();
        String debugModel = environment.getProperty("pathProperty.debug");
        if ("true".equals(debugModel)) {
            entity.put("retCode", "200");
            return entity;
        }
        Map<String, Object> parametersMap = null;

        HashMap interfaceMap = callInterFaceDao.getInterface(code);
        // 接口url
        String url = null;
        // 接口请求方式
        String method = null;
        // 接口请求头
        String headers = null;

        Map headersMap = new HashMap();
        if (interfaceMap == null || interfaceMap.isEmpty()) {
            entity.put("retCode", "201");
            entity.put("message", "未查询到业务接口【" + name + "】，无法调用接口！");
            return entity;
        }
        // 参数处理
        try {
            url = interfaceMap.get("url").toString();
            method = interfaceMap.get("request_method").toString();
            // 目前仅支持GET和POST调用
            if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST")) {
                entity.put("retCode", "201");
                entity.put("message", "目前业务接口调用仅支持GET和POST方式！");
                return entity;
            }
            headers = interfaceMap.get("request_headers").toString();
            headersMap = (Map<String, String>) JSONObject.parse(headers);
            // get方式调用m
            if (method.equalsIgnoreCase("GET")) {
//                parametersMap = JSONObject.parseObject(parameters, Map.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            entity.put("retCode", "201");
            entity.put("message", "业务接口【" + name + "】，调用参数处理失败！失败原因：" + e.getMessage());
            return entity;
        }
        String parameters = "";
        /*{
            "url":"网闸另一端第三方业务系统的数据接收接口url，必选",
                "sendSys":"发送方业务系统名称，必选",3-14新增
	        	"sendScenario":"发送方业务场景名称，必选",3-14新增
	        	"targetSys":"网闸另一端第三方业务系统的名称，必选",3-14新增
                "method":"网闸另一端第三方业务系统的数据接收接口请求方式，GET|POST|PUT|DELETE，必选",
                "header":"网闸另一端第三方业务系统的数据接收接口请求头，可以不选",
                "BData":"通过Base64加密的自定义业务数据字符串，必选",
                "auditMap":"网闸需要的审核数据，一般情况下必选，也可以不选，使用默认审核数据"
        }*/
        //调用网闸所需参数组装
        JSONObject tmp = new JSONObject();
        String url2 = environment.getProperty("pathProperty.url");
        tmp.put("url", url2);
        tmp.put("method", method);
        tmp.put("BData", BData);
        tmp.put("sendSys", "分拣系统");
        tmp.put("targetSys", "MES系统");
        tmp.put("sendScenario", sendScenario);
        parameters = tmp.toJSONString();

        // 开始请求接口
        String result = null;
        try {
            if (method.equalsIgnoreCase("GET")) {
                result = HttpUtil.createGet(url)
                        .addHeaders(headersMap)
                        .form(parametersMap)
                        .charset("UTF-8")
                        .timeout(30000)
                        .execute()
                        .body();
            } else {
                result = HttpUtil.createPost(url)
                        .addHeaders(headersMap)
                        .body(parameters)
                        .charset("UTF-8")
                        .timeout(30000)
                        .execute()
                        .body();
            }
            System.out.println("=====================业务数据result:" + result);
            entity.put("retCode", "200");
            entity.put("message", result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return entity;
    }
}
